package com.um.jdy.ykc.rpc.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.um.jdy.rpc.api.ev.RpcEVYkcDeviceService;
import com.um.jdy.rpc.entity.EVDeviceParams;
import com.um.jdy.rpc.entity.EVUpgradeParams;
import com.um.jdy.rpc.entity.ykc.EVYkcDeviceParams;
import com.um.jdy.rpc.entity.ykc.EVYkcUpgradeParams;
import com.um.jdy.rpc.ev.confirmation.*;
import com.um.jdy.rpc.ev.entity.EVStartChargeParams;
import com.um.jdy.rpc.ev.enums.ConfirmationStatus;
import com.um.jdy.rpc.ev.enums.RestartExecuteType;
import com.um.jdy.ykc.command.*;
import com.um.jdy.ykc.model.PriceModel;
import com.um.jdy.ykc.netty.NettyContextHolder;
import com.um.jdy.ykc.netty.YkcCommandHandler;
import com.um.jdy.ykc.service.PriceModelService;
import com.um.springcloud.dubbo.cluster.DeviceKey;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * 充电业务操作
 *
 * @author 邓南辉
 * 日期 2022/7/4
 * 版权所有 广州优匠科技有限公司
 */
@Slf4j
@Service
@DubboService
public class RpcEVDeviceServiceImpl extends RpcService implements RpcEVYkcDeviceService {

    @Autowired
    YkcCommandHandler channelHandler;

    @Autowired
    PriceModelService priceModelService;

    /**
     * 发起充电 cmd_34
     * @param imei        IMEI码
     * @param port       枪号
     * @param params  额外参数
     */
    @Override
    public void startCharge(DeviceKey imei, Integer port, EVStartChargeParams params) {
        ChannelHandlerContext context = NettyContextHolder.getDeviceContext(imei.getKey());
        if(context == null) {
            log.error("设备[{}]不在线！", imei.getKey());
            return;
        }

        int heartNum = NettyContextHolder.getHeartNum(context.channel().id().asLongText());
        Cmd34ServerStartChargeRequest request = new Cmd34ServerStartChargeRequest(heartNum,params.getTransactionNo(),imei.getKey(),port,params.getCardNo(),
                params.getPhysicsNo(),params.getBalance() / 100.0);
        channelHandler.sendClient(request, context);

//        return delayGetConfirmation(context, request,Cmd33ServerStartChargeResponse.class, new RpcCallback() {
//            @Override
//            public BaseConfirmation getConfirmation(String key) {
//                Cmd33ServerStartChargeResponse startChargeResponse = channelHandler.getResp(key);
//                if(startChargeResponse == null)
//                    return null;
//
//                RemoteStartTransactionConfirmation confirmation = new RemoteStartTransactionConfirmation();
//                if(startChargeResponse.getStatus() == 1){
//                    confirmation.setStatus(ConfirmationStatus.Accepted);
//                }else{
//                    confirmation.setStatus(ConfirmationStatus.Rejected);
//                    confirmation.setReason(startChargeResponse.getFaultReason()+"失败说明");
//                }
//                return confirmation;
//            }
//        });
    }

    /**
     * 发起充电并下发计费模型 cmd_34
     * @param transactionNo    交易流水号
     * @param code        IMEI码
     * @param gunNo       枪号
     * @param cardNo      逻辑卡号
     * @param balance     余额
     * @param resp     计费模型
     */
//    @Override
//    public StartChargeResp startCharge(String transactionNo,String code, Integer gunNo,String cardNo,String physicsNo, Double balance, PriceModelResp resp) {
//        ChannelHandlerContext context = NettySocketHolder.getDeviceContext(code);
//        if(context == null) {
//            log.error("设备[{}]不在线！", code);
//            return null;
//        }
//
//        int heartNum = NettySocketHolder.getHeartNum(context.channel().id().asLongText());
//        Cmd58UpdatePriceModelRequest request = new Cmd58UpdatePriceModelRequest(heartNum,resp.getCode(),resp.getFeeMode(),
//                resp.getSharpFee(),resp.getSharpServiceFee(),resp.getPeakFee(),resp.getPeakServiceFee(),resp.getShoulderFee(),
//                resp.getShoulderServiceFee(),resp.getOffPeakFee(),resp.getOffPeakServiceFee(),resp.getLossScale(),resp.getTime48Fee());
//
//        channelHandler.sendClient(request, context);
//        UpdatePriceModelResp updatePriceModelResp = delayGetResp(context, Cmd57UpdatePriceModelResponse.class,
//                key -> BeanUtil.copyProperties(channelHandler.getResp(key), UpdatePriceModelResp.class));
//
//        if(updatePriceModelResp.getResult() == 1){
//            return this.startCharge(transactionNo, code, gunNo, cardNo, physicsNo, balance);
//        }
//
//        log.error("设备[{}]下发计费模型失败", code);
//        StartChargeResp startChargeResp = new StartChargeResp();
//        startChargeResp.setTransactionNo(transactionNo);
//        startChargeResp.setCode(code);
//        startChargeResp.setGunNo(gunNo);
//        startChargeResp.setStatus(0);
//        startChargeResp.setFaultReason(0);
//        return startChargeResp;
//    }

    /**
     * 停止充电 cmd_36
     *
     * @param imei   桩编号
     * @param port  枪号
     */
    @Override
    public void stopCharge(DeviceKey imei, Integer port) {
        ChannelHandlerContext context = NettyContextHolder.getDeviceContext(imei.getKey());
        if(context == null) {
            log.error("设备[{}]不在线！", imei.getKey());
            return;
        }

        int heartNum = NettyContextHolder.getHeartNum(context.channel().id().asLongText());
        Cmd36ServerStopChargeRequest request = new Cmd36ServerStopChargeRequest(heartNum,imei.getKey(),port);
        channelHandler.sendClient(request, context);

//        return delayGetConfirmation(context, request, Cmd35ServerStopChargeResponse.class,new RpcCallback() {
//            @Override
//            public BaseConfirmation getConfirmation(String key) {
//                Cmd35ServerStopChargeResponse stopChargeResponse = channelHandler.getResp(key);
//                if(stopChargeResponse == null)
//                    return null;
//
//                RemoteStopTransactionConfirmation confirmation = new RemoteStopTransactionConfirmation();
//                if (stopChargeResponse.getStatus() == 1) {
//                    confirmation.setStatus(ConfirmationStatus.Accepted);
//                } else {
//                    confirmation.setStatus(ConfirmationStatus.Rejected);
//                    confirmation.setReason(stopChargeResponse.getFaultReason() + "失败说明");
//                }
//                return confirmation;
//            }
//        });
    }

    /**
     * 请求设备数据 cmd_12
     *
     * @param code   IMEI码
     * @param gunNo  枪号
     */
//    @Override
//    public void requestDeviceData(String code, Integer gunNo) {
//        ChannelHandlerContext context = NettySocketHolder.getDeviceContext(code);
//        if(context == null) {
//            log.error("设备[{}]不在线！", code);
//            return;
//        }
//
//        int heartNum = NettySocketHolder.getHeartNum(context.channel().id().asLongText());
//        Cmd12ReadRealtimeData request = new Cmd12ReadRealtimeData(heartNum,code,gunNo);
//        channelHandler.sendClient(request, context);
//    }

    /**
     * 更新余额 cmd_42
     * @param imei IMEI码
     * @param port 枪号
     * @param cardNo 物理卡号
     * @param balance 账户余额
     */
    @Override
    public UpdateBalanceConfirmation updateBalance(DeviceKey imei, Integer port, String cardNo, Integer balance) {
        ChannelHandlerContext context = NettyContextHolder.getDeviceContext(imei.getKey());
        if(context == null) {
            log.error("设备[{}]不在线！", imei.getKey());
            return null;
        }

        int heartNum = NettyContextHolder.getHeartNum(context.channel().id().asLongText());
        Cmd42UpdateBalanceRequest request = new Cmd42UpdateBalanceRequest(heartNum,imei.getKey(),port,cardNo,balance);
        channelHandler.sendClient(request, context);

        return delayGetConfirmation(context,  request,new RpcCallback() {
            @Override
            public BaseConfirmation getConfirmation(String key) {
                Cmd41UpdateBalanceResponse updateBalanceResponse = channelHandler.getResp(key);
                if(updateBalanceResponse == null)
                    return null;

                UpdateBalanceConfirmation confirmation = new UpdateBalanceConfirmation();
                if (updateBalanceResponse.getStatus() == 0) {
                    confirmation.setStatus(ConfirmationStatus.Accepted);
                } else {
                    confirmation.setStatus(ConfirmationStatus.Rejected);
                    confirmation.setReason(updateBalanceResponse.getStatus() == 1 ? "设备编号错误" : "卡号错误");
                }
                return confirmation;
            }
        });
    }


    /**
     * 对时设置 cmd_56
     * @param imei        IMEI码
     * @param datetime    时间
     */
    @Override
    public UpdateTimeConfirmation updateTime(DeviceKey imei, Date datetime){
        ChannelHandlerContext context = NettyContextHolder.getDeviceContext(imei.getKey());
        if(context == null) {
            log.error("设备[{}]不在线！", imei.getKey());
            return null;
        }

        int heartNum = NettyContextHolder.getHeartNum(context.channel().id().asLongText());
        Cmd56UpdateTimeRequest request = new Cmd56UpdateTimeRequest(heartNum,imei.getKey(),new Date());
        channelHandler.sendClient(request, context);

        return delayGetConfirmation(context, request,new RpcCallback() {
            @Override
            public BaseConfirmation getConfirmation(String key) {
                Cmd55UpdateTimeResponse updateTimeResponse = channelHandler.getResp(key);
                if(updateTimeResponse == null)
                    return null;

                UpdateTimeConfirmation confirmation = new UpdateTimeConfirmation();
                long between = DateUtil.between(datetime, updateTimeResponse.getNowTime(), DateUnit.MINUTE);
                if (between <= 1) {
                    confirmation.setStatus(ConfirmationStatus.Accepted);
                } else {
                    confirmation.setStatus(ConfirmationStatus.Rejected);
                }
                return confirmation;
            }
        });

    }

    /**
     * cmd_92
     * 设备远程重启
     * @param imei IMEI码
     * @param restartExecuteType 0x01：立即执行 0x02：空闲执行
     */
    @Override
    public RemoteRestartConfirmation restart(DeviceKey imei, RestartExecuteType restartExecuteType){
        ChannelHandlerContext context = NettyContextHolder.getDeviceContext(imei.getKey());
        if(context == null) {
            log.error("设备[{}]不在线！", imei.getKey());
            return null;
        }

        int heartNum = NettyContextHolder.getHeartNum(context.channel().id().asLongText());
        Cmd92RebootDeviceRequest request = new Cmd92RebootDeviceRequest(heartNum,imei.getKey(),restartExecuteType == RestartExecuteType.Now ? 1 : 2);
        channelHandler.sendClient(request, context);

        // 重启不用等设备回复
        RemoteRestartConfirmation confirmation = new RemoteRestartConfirmation();
        confirmation.setStatus(ConfirmationStatus.Accepted);
        return confirmation;
//        return delayGetConfirmation(context, request,new RpcCallback() {
//            @Override
//            public BaseConfirmation getConfirmation(String key) {
//                Cmd91RebootDeviceResponse rebootDeviceResponse = channelHandler.getResp(key);
//                if(rebootDeviceResponse == null)
//                    return null;
//
//                RemoteRestartConfirmation confirmation = new RemoteRestartConfirmation();
//                if (rebootDeviceResponse.getStatus() == 1) {
//                    confirmation.setStatus(ConfirmationStatus.Accepted);
//                } else {
//                    confirmation.setStatus(ConfirmationStatus.Rejected);
//                }
//                return confirmation;
//            }
//        });
    }


    /**
     * 远程设置设置参数 cmd_51
     * @param imei IMEI码
     * @param params 参数
     */
    @Override
    public SetParametersConfirmation setParameters(DeviceKey imei, EVDeviceParams params){
        ChannelHandlerContext context = NettyContextHolder.getDeviceContext(imei.getKey());
        if(context == null) {
            log.error("设备[{}]不在线！", imei.getKey());
            return null;
        }

        EVYkcDeviceParams ykcDeviceParams = (EVYkcDeviceParams)params;
        int heartNum = NettyContextHolder.getHeartNum(context.channel().id().asLongText());
        Cmd52UpdateSettingsRequest request = new Cmd52UpdateSettingsRequest(heartNum,imei.getKey(),ykcDeviceParams.getUseStatus(),ykcDeviceParams.getMaxPower());
        channelHandler.sendClient(request, context);

        SetParametersConfirmation confirmation = new SetParametersConfirmation();
        confirmation.setStatus(ConfirmationStatus.Accepted);
        return confirmation;

//        return delayGetConfirmation(context, request, new RpcCallback() {
//            @Override
//            public BaseConfirmation getConfirmation(String key) {
//                Cmd51UpdateSettingsResponse updateSettingsResponse = channelHandler.getResp(key);
//                if(updateSettingsResponse == null)
//                    return null;
//
//                SetParametersConfirmation confirmation = new SetParametersConfirmation();
//                if (updateSettingsResponse.getResult() == 1) {
//                    confirmation.setStatus(ConfirmationStatus.Accepted);
//                } else {
//                    confirmation.setStatus(ConfirmationStatus.Rejected);
//                }
//                return confirmation;
//            }
//        });

    }


    /**
     * cmd_94
     * 设备远程升级更新
     * @param imei IMEI码
     * @param params 升级参数
     */
    @Override
    public void upgrade(DeviceKey imei,EVUpgradeParams params){
        ChannelHandlerContext context = NettyContextHolder.getDeviceContext(imei.getKey());
        if(context == null) {
            log.error("设备[{}]不在线！", imei.getKey());
            return;
        }

        EVYkcUpgradeParams ykcUpgradeParams = (EVYkcUpgradeParams)params;
        int heartNum = NettyContextHolder.getHeartNum(context.channel().id().asLongText());
        Cmd94UpgradeDeviceRequest request = new Cmd94UpgradeDeviceRequest(heartNum,imei.getKey(),ykcUpgradeParams.getMode(),ykcUpgradeParams.getPower(),
                ykcUpgradeParams.getHost(),ykcUpgradeParams.getPort(),ykcUpgradeParams.getUsername(),ykcUpgradeParams.getPassword(),
                ykcUpgradeParams.getUrl(),ykcUpgradeParams.getExeType(),ykcUpgradeParams.getTimeout());
        channelHandler.sendClient(request, context);

//        return delayGetConfirmation(context, request, new RpcCallback() {
//            @Override
//            public BaseConfirmation getConfirmation(String key) {
//                Cmd93UpgradeDeviceResponse upgradeDeviceResponse = channelHandler.getResp(key);
//                if(upgradeDeviceResponse == null)
//                    return null;
//
//                RemoteUpgradeConfirmation confirmation = new RemoteUpgradeConfirmation();
//                if (upgradeDeviceResponse.getStatus() == 0) {
//                    confirmation.setStatus(ConfirmationStatus.Accepted);
//                } else {
//                    confirmation.setStatus(ConfirmationStatus.Rejected);
//                    if(upgradeDeviceResponse.getStatus() == 1){
//                        confirmation.setReason("编号错误");
//                    }else if(upgradeDeviceResponse.getStatus() == 2){
//                        confirmation.setReason("程序与桩型号不符");
//                    }else{
//                        confirmation.setReason("下载更新文件超时");
//                    }
//                }
//                return confirmation;
//            }
//        });

    }

    /**
     * cmd_58
     * 设置计费模型
     * @param imei IMEI码
     */
    @Override
    public SetPriceModelConfirmation setPriceModel(DeviceKey imei){
        ChannelHandlerContext context = NettyContextHolder.getDeviceContext(imei.getKey());
        if(context == null) {
            log.error("设备[{}]不在线！", imei.getKey());
            return null;
        }

        PriceModel model = priceModelService.getPriceModel(imei.getKey());
        if(model == null){
            log.error("计费模型[{}]不存在！", imei);
            return null;
        }

        int heartNum = NettyContextHolder.getHeartNum(context.channel().id().asLongText());
        Cmd58UpdatePriceModelRequest request = new Cmd58UpdatePriceModelRequest(heartNum,imei.getKey(),model.getFeeMode(),
                model.getSharpFee(),model.getSharpServiceFee(),model.getPeakFee(),model.getPeakServiceFee(),model.getShoulderFee(),
                model.getShoulderServiceFee(),model.getOffPeakFee(),model.getOffPeakServiceFee(),model.getLossScale(),model.getTime48Fee());
        channelHandler.sendClient(request, context);

        // 下发计费不用等设备回复
        SetPriceModelConfirmation confirmation = new SetPriceModelConfirmation();
        confirmation.setStatus(ConfirmationStatus.Accepted);
        return confirmation;

//        return delayGetConfirmation(context, request,new RpcCallback() {
//            @Override
//            public BaseConfirmation getConfirmation(String key) {
//                Cmd57UpdatePriceModelResponse updatePriceModelResponse = channelHandler.getResp(key);
//                if(updatePriceModelResponse == null)
//                    return null;
//
//                SetPriceModelConfirmation confirmation = new SetPriceModelConfirmation();
//                if (updatePriceModelResponse.getResult() == 1) {
//                    confirmation.setStatus(ConfirmationStatus.Accepted);
//                } else {
//                    confirmation.setStatus(ConfirmationStatus.Rejected);
//                }
//                return confirmation;
//            }
//        });


    }
}
